﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Net;

namespace LinkViewer
{
    /// <summary>
    /// Interaction logic for Checker.xaml
    /// </summary>
    public partial class Checker : Window
    {

        BackgroundWorker worker = null;
        BackgroundWorker checker = null;
        List<jcc.com.dailyez.Link> links = new List<jcc.com.dailyez.Link>();

        ObservableCollectionEx<LinkWrapper> linkCollection = new ObservableCollectionEx<LinkWrapper>();

        public ObservableCollectionEx<LinkWrapper> LinkCollection
        { get { return linkCollection; } }
        public Checker()
        {
            InitializeComponent();
            worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.WorkerReportsProgress = true;


            checker = new BackgroundWorker();
            checker.DoWork += new DoWorkEventHandler(checker_DoWork);
            checker.ProgressChanged += new ProgressChangedEventHandler(checker_ProgressChanged);
            checker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(checker_RunWorkerCompleted);
            checker.WorkerReportsProgress = true;
            // linksListView.DataContext = links;
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progBar.Value = e.ProgressPercentage;
            App.ResetIdleTimer();
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            foreach (jcc.com.dailyez.Link link in links)
                linkCollection.Add(new LinkWrapper(link));

            bChooseFolder.IsEnabled = true;

            //allow for checking if there are more than one link
            if (linkCollection.Count > 1)
                bCheckLinks.IsEnabled = true;
            statusActivity.Content = "Link Extraction Complete";
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            jcc.Helpers.folderWrapper wrapper = e.Argument as jcc.Helpers.folderWrapper;

            jcc.com.dailyez.Page[] pages = jcc.StandardWebService.WebService.GetAllPages(jcc.StandardWebService.GetKey(), wrapper.ID);
            statusActivity.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { statusActivity.Content = "Extracting links from pages "; }));

            double counter = 0;
            double pageCount = pages.Length;
            foreach (jcc.com.dailyez.Page p in pages)
            {
                links.AddRange(jcc.StandardWebService.WebService.GetLinksFromPage(jcc.StandardWebService.GetKey(), p.ID));
                counter++;


                double f = counter / pageCount;

                worker.ReportProgress((int)(f * 100));
            }
        }

        private void bChooseFolder_Click(object sender, RoutedEventArgs e)
        {
            jcc.DlgSelectFolder selFolder = new jcc.DlgSelectFolder("Select a folder to check");

            if (selFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                worker.RunWorkerAsync(selFolder.SelectedFolder);
                bChooseFolder.IsEnabled = false;
                statusActivity.Content = "Connecting to Link Database";
            }
        }

        private void bCheckLinks_Click(object sender, RoutedEventArgs e)
        {
            checker.RunWorkerAsync();
        }

        void checker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }

        void checker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progBar.Value = e.ProgressPercentage;
            App.ResetIdleTimer();
           
        }

        void checker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] whiteList = jcc.StandardWebService.WebService.GetLinkCheckerWhitelist();
            for (int i = 0; i < LinkCollection.Count; i++)
            {
           
                if (whiteList.Contains(LinkCollection[i].URL))
                    continue;
                try
                {
                    statusActivity.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { statusActivity.Content = "Checking " + LinkCollection[i].URL; }));
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(LinkCollection[i].URL);
                    request.Timeout = 15000;
                    HttpWebResponse response;


                    response = (HttpWebResponse)request.GetResponse();
                    LinkCollection[i].Status_Code = (int)response.StatusCode;

                }
                catch (WebException x)
                {
                    HttpWebResponse r = (HttpWebResponse)x.Response;
                    if (r == null)
                        LinkCollection[i].Status_Code = 600;
                    else
                        LinkCollection[i].Status_Code = (int)r.StatusCode;

                }
                catch (Exception x)
                {

                }
                App.ResetIdleTimer();
                LinkCollection[i].IsChecked = true;
                statusActivity.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { statusActivity.Content = "Returned status code " + LinkCollection[i].Status_Code + " from " + LinkCollection[i].URL; }));

                //handle it
                DirectoryLink link = new DirectoryLink();
                link.Link = LinkCollection[i].Original_Link;

                switch (LinkCollection[i].Status_Code)
                {
                    case 400:
                    case 404:
                    case 600:
                    case 500:
                        link.Suspended = true;
                        break;
                    case 301:
                        link.Elevated = true;
                        break;

                }


                double progress = (double)i / (double)LinkCollection.Count;

                checker.ReportProgress((int)(progress * 100));
            }
        }

    }
}
